import re
import urllib
from datetime import datetime
from django.utils.datastructures import SortedDict
from BeautifulSoup import BeautifulSoup

from time import sleep

import dbs as dbs

import pygtk
pygtk.require( '2.0' )
import gtk


import dpcDBs as dbs
from gui.helperFuncs import genCallbackCheckButton





class dpcPreferences( gtk.Dialog ):
  # On-change callbacks 
  def adjustmentChanged( self, entry, data = None ):
    p = entry.value
    if p < 1 or p > 100:
      p = 5
    self.settings.setField( data, int( p ) )
    self.callback( self.settings )

  def entryChanged( self, entry, data = None ):
    self.settings.setField( data, entry.get_text() )
    self.callback( self.settings )

  def checkButtonToggled( self, cb, label = None ):
    self.settings.setField( label, cb.get_active() )
    self.callback( self.settings )




  def __init__( self, callback ):
    gtk.Dialog.__init__( self, 'Preferences', None,
           gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
           None )
    self.set_position( gtk.WIN_POS_CENTER_ALWAYS )

    # Get settings, and notify parent
    self.settings = dbs.settingsTable.getSettings()
    callback( self.settings )
    self.callback = callback
    self.set_modal( False )

    # Initialise frames etc
    self.current_frame = None
    self.create_gui()
    self.set_modal( True )
    gtk.main()
    self.set_modal( False )

  def create_gui( self ):
    self.settings = dbs.settingsTable.getSettings()

    model = gtk.ListStore( str, gtk.gdk.Pixbuf )

    img = gtk.Image()
    img.set_from_stock( gtk.STOCK_COLOR_PICKER, gtk.ICON_SIZE_BUTTON )

    #pixbuf = gtk.gdk.pixbuf_new_from_file( 'dpc.ico' )
    #pixbuf = gtk.gdk.pixbuf_new_from_file( 'dpc.ico' )
    model.append( ['Login', None] )
    model.append( ['Proxy', None] )
    model.append( ['Logging', None] )
    model.append( ['Chart', None] )
    model.append( ['Refresh', None] )
    model.append( ['Notify', None] )


    self.icon_view = gtk.IconView( model )
    self.icon_view.set_text_column( 0 )
    self.icon_view.set_pixbuf_column( 1 )
    self.icon_view.set_orientation( gtk.ORIENTATION_VERTICAL )
    self.icon_view.set_selection_mode( gtk.SELECTION_SINGLE )
    self.icon_view.connect( 'selection-changed', self.on_select, model )
    self.icon_view.set_columns( 1 )
    self.icon_view.set_item_width( -1 )
    self.icon_view.set_size_request( 72, -1 )

    self.content_box = gtk.HBox( False )
    self.content_box.pack_start( self.icon_view, fill = True, expand = False )
    self.icon_view.select_path( ( 0, ) ) # select a category, will create frame
    self.show_all()
    self.vbox.pack_start( self.content_box )
    self.set_size_request( 400, 500 )
    self.show_all()

  def on_select( self, icon_view, model = None ):
    selected = icon_view.get_selected_items()
    if len( selected ) == 0:
      return
    i = selected[0][0]
    category = model[i][0]
    if self.current_frame is not None:
      self.content_box.remove( self.current_frame )
      self.current_frame.destroy()
      self.current_frame = None

    if category == 'Login':
      self.current_frame = self.createLoginFrame()
    elif category == 'Proxy':
      self.current_frame = self.createProxyFrame()
    elif category == 'Logging':
      self.current_frame = self.createLoggingFrame()
    elif category == 'Chart':
      self.current_frame = self.createChartFrame()
    elif category == 'Refresh':
      self.current_frame = self.createRefreshFrame()
    elif category == 'Notify':
      self.current_frame = self.createNotifyFrame()

    self.content_box.pack_end( self.current_frame, fill = True, expand = True )
    self.show_all()






  def addItem( self, frame, item ):
    tabTable = gtk.Table()
    tabTable.attach( item, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 5, 5 );
    tabTable.set_border_width( 10 )
    tabTable.set_row_spacings( 10 )
    tabTable.set_col_spacings( 10 )
    tabTable.show()
    item.show()

    # Attach to the notebook
    frame.add( tabTable )
    return frame



  def addItems( self, frame, settings ):
    tabTable = gtk.Table()
    i = 0
    for ek, ww in settings.iteritems():
      if ek and len( ek ):
        wl = gtk.Label( ek )
        tabTable.attach( wl, 0, 1, i, i + 1, gtk.FILL, gtk.FILL, 5, 5 );
        tabTable.attach( ww, 1, 2, i, i + 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 5, 5 );
        wl.show()
      else:
        tabTable.attach( ww, 0, 2, i, i + 1, gtk.FILL | gtk.EXPAND, gtk.FILL, 5, 5 );

      ww.show()

      i += 1

    tabTable.set_border_width( 10 )
    tabTable.set_row_spacings( 10 )
    tabTable.set_col_spacings( 10 )
    tabTable.show()

    # Attach to the notebook
    frame.add( tabTable )
    return frame






  def createLoginFrame( self ):
    frame = gtk.Frame( 'Login settings' )

    settings = SortedDict()

    e = gtk.Entry()
    e.set_text( self.settings.login_username )
    e.connect( "changed", self.entryChanged, "login_username" )
    settings["Username"] = e

    e = gtk.Entry()
    e.set_text( self.settings.login_password )
    e.set_visibility( False )
    e.connect( "changed", self.entryChanged, "login_password" )
    settings["Password"] = e

    return self.addItems( frame, settings )

  def createProxyFrame( self ):
    frame = gtk.Frame( 'Proxy settings' )

    settings = SortedDict()

    e = gtk.Entry()
    e.set_text( self.settings.proxy_address )
    e.connect( "preedit-changed", self.entryChanged, "proxy_address" )
    settings["Proxy address"] = e

    e = gtk.Entry()
    e.set_text( self.settings.proxy_port )
    e.connect( "preedit-changed", self.entryChanged, "proxy_port" )
    settings["Proxy port"] = e

    e = gtk.Entry()
    e.set_text( self.settings.proxy_username )
    e.connect( "preedit-changed", self.entryChanged, "proxy_username" )
    settings["Proxy username"] = e

    e = gtk.Entry()
    e.set_text( self.settings.proxy_password )
    e.connect( "preedit-changed", self.entryChanged, "proxy_password" )
    settings["Proxy password"] = e

    return self.addItems( frame, settings )

  def createLoggingFrame( self ):
    frame = gtk.Frame( 'Logging settings' )

    settings = SortedDict()

    e = gtk.CheckButton()
    e.set_active( self.settings.logging_i )
    e.connect( "toggled", self.checkButtonToggled, "logging_i" )
    settings["Log information messages"] = e

    e = gtk.CheckButton()
    e.set_active( self.settings.logging_w )
    e.connect( "toggled", self.checkButtonToggled, "logging_w" )
    settings["Log warning messages"] = e

    e = gtk.CheckButton()
    e.set_active( self.settings.logging_e )
    e.connect( "toggled", self.checkButtonToggled, "logging_e" )
    settings["Log error messages"] = e

    return self.addItems( frame, settings )

  def createChartFrame( self ):
    frame = gtk.Frame( 'Chart settings' )
    return frame

  def createNotifyFrame( self ):
    frame = gtk.Frame( 'Settings for notifications when scores change' )

    settings = SortedDict()

    e = gtk.CheckButton()
    e.set_active( self.settings.notify_popup )
    e.connect( "toggled", self.checkButtonToggled, "notify_popup" )
    settings["Pop up notification window"] = e

    """
    adjustment = gtk.Adjustment( 1.0, 1.0, 100.0, 1.0, 10.0, 1.0 );
    adjustment.connect( "value_changed", self.adjustmentChanged, "notify_popupTime" )
    e = gtk.HScale( adjustment )
    e.set_update_policy( gtk.UPDATE_DISCONTINUOUS )
    e.set_value( self.settings.notify_popupTime )
    settings["Length of popup window"] = e
    """


    e = gtk.CheckButton()
    e.set_active( self.settings.notify_popup )
    e.connect( "toggled", self.checkButtonToggled, "notify_sound" )
    settings["Play a sound"] = e



    # Displays
    h = gtk.VBox()

    f = gtk.Frame( "GENERAL" )
    t = gtk.Table()
    i = 0
    genCallbackCheckButton( t, i, "Popup notification window", self.checkButtonToggled, "notify_popup", self.settings.notify_popup ); i += 1
    genCallbackCheckButton( t, i, "Play notification sound", self.checkButtonToggled, "notify_sound", self.settings.notify_sound ); i += 1
    f.add( t )
    h.pack_start( f )

    h.pack_start( gtk.Label( "" ) )


    f = gtk.Frame( "VIEW (window)" )
    t = gtk.Table()
    i = 0
    genCallbackCheckButton( t, i, "Show entry name", self.checkButtonToggled, "notify_ename", self.settings.notify_ename ); i += 1
    genCallbackCheckButton( t, i, "Show challenge name", self.checkButtonToggled, "notify_cname", self.settings.notify_cname ); i += 1
    genCallbackCheckButton( t, i, "Show last interpreted vote", self.checkButtonToggled, "notify_lastVote", self.settings.notify_lastVote ); i += 1
    genCallbackCheckButton( t, i, "Show #votes", self.checkButtonToggled, "notify_votes", self.settings.notify_votes ); i += 1
    genCallbackCheckButton( t, i, "Show #views", self.checkButtonToggled, "notify_views", self.settings.notify_views ); i += 1
    genCallbackCheckButton( t, i, "Show score", self.checkButtonToggled, "notify_score", self.settings.notify_score ); i += 1
    genCallbackCheckButton( t, i, "Show #comments", self.checkButtonToggled, "notify_comments", self.settings.notify_comments ); i += 1
    genCallbackCheckButton( t, i, "Show #favourites", self.checkButtonToggled, "notify_favourites", self.settings.notify_favourites ); i += 1
    genCallbackCheckButton( t, i, "Show #wish lists", self.checkButtonToggled, "notify_wishList", self.settings.notify_wishList ); i += 1
    f.add( t )
    h.pack_start( f )




    return self.addItem( frame, h )

  def createRefreshFrame( self ):
    frame = gtk.Frame( 'Refresh settings' )

    settings = SortedDict()

    e = gtk.CheckButton()
    e.set_active( self.settings.update_auto )
    e.connect( "toggled", self.checkButtonToggled, "update_auto" )
    settings["Refresh automatically"] = e

    adjustment = gtk.Adjustment( 1.0, 1.0, 100.0, 1.0, 10.0, 1.0 );
    adjustment.connect( "value_changed", self.adjustmentChanged, "update_period" )
    e = gtk.HScale( adjustment )
    e.set_update_policy( gtk.UPDATE_DISCONTINUOUS )
    e.set_value( self.settings.update_period )
    settings["Update period"] = e

    return self.addItems( frame, settings )


def main():
  def callback( s ):
    pass

  dbs.validateDBs()
  p = gui_preferences( callback )
  p.show()

  gtk.main()
  return 0

if __name__ == "__main__":
  main()


